﻿using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows;

namespace Coding4Fun.UsbCannon.HttpListener
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		readonly System.Net.HttpListener _listener = new System.Net.HttpListener();
		readonly BackgroundWorker _worker = new BackgroundWorker();
		readonly Rocket _launcher = new Rocket();

		public MainWindow()
		{
			InitializeComponent();
			_launcher.Connect();
		}

		private void Window_Loaded(object sender, RoutedEventArgs e)
		{
			CreateListener("http://+:31337/");
			_worker.DoWork += WorkerDoWork;
			
			_worker.RunWorkerAsync();
			netBios.Text = Environment.MachineName;
		}

		void WorkerDoWork(object sender, DoWorkEventArgs e)
		{
			ListeningThread();
		}

		public void CreateListener(params string[] prefixes)
		{
			if (!System.Net.HttpListener.IsSupported)
			{
				MessageBox.Show("Please use Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role not supported), Windows Server 2003 SP2");
				return;
			}
			// URI prefixes are required,
			// for example "http://contoso.com:8080/index/".
			if (prefixes == null || prefixes.Length == 0)
				throw new ArgumentException("prefixes");

			// Add the prefixes.
			foreach (string s in prefixes)
				_listener.Prefixes.Add(s);

			_listener.Start();
		}

		public void ListeningThread()
		{
			while (_listener.IsListening)
			{
				// Note: The GetContext method blocks while waiting for a request. 
				var context = _listener.GetContext();

				var request = context.Request;
				UpdateUI(request.Url.Query);

				handleUSB(request.QueryString["command"]);

				// Obtain a response object.
				var response = context.Response;
				// Construct a response.
				var responseString = "<HTML><BODY>" + request.Url.Query + ":::" + DateTime.Now + "</BODY></HTML>";
				var buffer = Encoding.UTF8.GetBytes(responseString);
				// Get a response stream and write the response to it.
				response.ContentLength64 = buffer.Length;

				using (Stream output = response.OutputStream)
					output.Write(buffer, 0, buffer.Length);
			}
		}

		private void handleUSB(string command)
		{
			switch (command)
			{
				case "left":
					_launcher.MoveLeft();
					break;
				case "right":
					_launcher.MoveRight();
					break;
				case "up":
					_launcher.MoveUp();
					break;
				case "down":
					_launcher.MoveDown();
					break;
				case "fire":
					_launcher.FireOnce();
					Thread.Sleep(5000);
					_launcher.StopAll();
					_launcher.MoveUp();
					_launcher.StopAll();
					break;
				case "off":
					_launcher.StopAll();
					break;
			}
		}

		private void UpdateUI(string command)
		{
			Dispatcher.BeginInvoke(new ThreadStart(() => { output.Text = command + Environment.NewLine + output.Text; }));
		}

		private void Window_Closed(object sender, EventArgs e)
		{
			_worker.CancelAsync();

			_listener.Close();
		}
	}

	public static class Extentions
	{
		public static bool HasValue(this string value)
		{
			return !string.IsNullOrWhiteSpace(value);
		}
	}
}
